#pragma once
#include"HashTable.h"


namespace MyUDmap {



	using namespace MyHashBucket;
	template<class K, class V>
	class unordered_map {

		typedef pair<const K, V> T;

		template<class T>
		struct KOfT {
			const K& operator()(const T& data)
			{
				return data.first;
			}
		};

	public:

		typedef typename hashTable< K,  T, KOfT<T>, HashFunc<K>>::Iterator iterator;
		typedef typename hashTable< K,  T, KOfT<T>, HashFunc<K>>::constIterator const_iterator;


		pair<iterator, bool> insert(const T& data)
		{
			return _hash.Insert(data);
		}
		V& operator[](const K& key)
		{
			return (insert(make_pair(key, V())).first)->second;
		}
		void print()
		{
			_hash.Print();
		}
		int size()
		{
			return _hash.Size();
		}
		iterator find(const T& key)
		{
			return _hash.Find(key);
		}
		const_iterator find(const T& key) const
		{
			return _hash.Find(key);
		}
		bool erase(const K& key)
		{
			return _hash.Erase(key);
		}

		iterator begin()
		{
			return _hash.Begin();
		}
		iterator end()
		{
			return _hash.End();
		}
		const_iterator cbegin()
		{
			return _hash.cBegin();
		}
		const_iterator cend()
		{
			return _hash.cEnd();
		}
	private:

		hashTable< K, T, KOfT<T>, HashFunc<K> > _hash;
	};

	void test1()
	{
		unordered_map<string, int> unmap;
		unmap.insert({ "string",1 });
		unmap.insert({ "sing",1 });
		unmap.insert({ "srin",1 });
		unmap.insert({ "ring",1 });
		unmap.print();
	}
	void test2()
	{
		unordered_map<string, int> unmap;

		vector<string> ve = { "left","right","mid","up","right","mid","up","down","mid","up","down", "right","mid" };
		for (auto& e : ve)
		{
			unmap[e]++;
		}

		auto it = unmap.begin();
		it->second = 10;
		//it->first = "ss";
		unmap.print();

	}

	void test3()
	{
		unordered_map<int, int> unmap;

		vector<int> ve = { 32,41,4235,54,123,6543,54,123,6543, };
		for (auto& e : ve)
		{
			unmap[e]++;
		}

		auto it = unmap.begin();
		it->second = 10;
		//it->first = 0;
		unmap.print();

		unmap.erase(32);
		unmap.print();

	}


}